package com.xbongbong.saas.help;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.AddressEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.pojo.dto.ButtonGetDTO;
import com.xbongbong.paas.pojo.dto.FormDataUpdateGetDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.errorcodes.InvoiceErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.formdata.pojo.SaasSpecialParamPojo;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.invoice.pojo.dto.CheckRedInvoiceDeletePojo;
import com.xbongbong.pro.invoice.pojo.dto.InvoiceAmountDetailDTO;
import com.xbongbong.pro.invoice.pojo.dto.InvoiceAmountDetailGetDTO;
import com.xbongbong.pro.invoice.pojo.vo.InvoiceAmountDetailVO;
import com.xbongbong.pro.purchaseinvoice.dto.PurchaseInvoiceAmountDetailGetDTO;
import com.xbongbong.pro.purchaseinvoice.vo.PurchaseInvoiceAmountDetailVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.InvoiceConstant;
import com.xbongbong.saas.domain.entity.InvoiceRelationshipEntity;
import com.xbongbong.saas.domain.entity.PurchaseInvoiceRelationshipEntity;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentSheetEntityExt;
import com.xbongbong.saas.domain.entity.ext.PurchaseEntityExt;
import com.xbongbong.saas.enums.CustomerExpressEnum;
import com.xbongbong.saas.enums.CustomerInvoiceEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.SheetAloneEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.InvoiceEnum;
import com.xbongbong.saas.enums.business.PayPlanEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.PurchaseInvoiceEnum;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.InvoiceRelationshipModel;
import com.xbongbong.saas.model.PayPlanSheetModel;
import com.xbongbong.saas.model.PaymentSheetModel;
import com.xbongbong.saas.model.PurchaseInvoiceRelationshipModel;
import com.xbongbong.saas.model.PurchaseModel;
import com.xbongbong.saas.service.InvoiceService;
import com.xbongbong.saas.service.PurchaseInvoiceService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getDoubleOrDefaultFromFormData;
import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

@Component
public class InvoiceCommonHelper extends BasicHelper{

    @Resource
    private SaasSaveHelp saasSaveHelp;
    @Resource
    private PurchaseInvoiceRelationshipModel purchaseInvoiceRelationshipModel;
    @Resource
    private FundHelp fundHelp;
    @Resource
    private PurchaseInvoiceService purchaseInvoiceService;
    @Resource
    private InvoiceRelationshipModel invoiceRelationshipModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    private PurchaseModel purchaseModel;
    @Resource
    private InvoiceService invoiceService;
    @Resource
    private PaymentSheetModel paymentSheetModel;
    @Resource
    private PayPlanSheetModel payPlanSheetModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private InvoiceHelp invoiceHelp;


    public void getMinusAmountFormRedInvoice(JSONObject data,JSONArray amountDetail,Long originId,Integer isImport,Integer businessType){
        InvoiceCommonHelp.getMinusAmountFormRedInvoice(data, amountDetail, originId, isImport, businessType);
    }


    private void invoiceOrPurchaseInvoiceRemoveSub(SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo,Map<Long,String> contractOrPurchaseMap,Map<Long,String> paymentOrPayPlanMap,Map<Long,String> paymentSheetOrPaySheetMap,
                                                   JSONObject data,JSONArray amountDetail,boolean isRed,Integer businessType,Integer contractOrPurchaseNum,Integer paymentOrPayPlanNum,Integer paymentSheetOrPaySheetNum) throws XbbException{
        JSONArray removeArray = new JSONArray();
        //这里如果是金额明细中有0元的就删掉
        if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())) {
            if (saasNeedRedundantAttrPojo.isContractUnion()) {
                commonRemoveSub(InvoiceEnum.CONTRACT_ID.getAttr(), InvoiceEnum.CONTRACT_ID_LINK_TEXT.getAttr(), data, amountDetail, contractOrPurchaseMap, isRed, removeArray, contractOrPurchaseNum);
            }
            if (saasNeedRedundantAttrPojo.isPaymentUnion()) {
                commonRemoveSub(InvoiceEnum.PAYMENT_ID.getAttr(), InvoiceEnum.PAYMENT_ID_LINK_TEXT.getAttr(), data, amountDetail, paymentOrPayPlanMap, isRed, removeArray, paymentOrPayPlanNum);
            }
            if (saasNeedRedundantAttrPojo.isPaymentSheetUnion()) {
                commonRemoveSub(InvoiceEnum.PAYMENT_SHEET_ID.getAttr(), InvoiceEnum.PAYMENT_SHEET_ID_LINK_TEXT.getAttr(), data, amountDetail, paymentSheetOrPaySheetMap, isRed, removeArray, paymentSheetOrPaySheetNum);
            }
            if (CollectionsUtil.isNotEmpty(amountDetail) && CollectionsUtil.isNotEmpty(removeArray)) {
                amountDetail.removeAll(removeArray);
            }
        }
        if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
            if(saasNeedRedundantAttrPojo.isPurchaseUnion()){
                commonRemoveSub(PurchaseInvoiceEnum.PURCHASE_ID.getAttr(),PurchaseInvoiceEnum.PURCHASE_ID_LINK_TEXT.getAttr(),data,amountDetail,contractOrPurchaseMap,isRed,removeArray,contractOrPurchaseNum);
            }

        }
    }



    /**
     * 复制销项发票的方法 后面切换helper
     * @param idAttr
     * @param noAttr
     * @param data
     * @param amountDetail
     * @param map
     * @param isRed
     * @param removeArray
     * @param num
     * @throws XbbException
     */
    public void commonRemoveSub(String idAttr,String noAttr,JSONObject data,JSONArray amountDetail,Map<Long,String> map,boolean isRed,JSONArray removeArray,Integer num) throws XbbException{
        //取最外层的关联实体
        JSONArray refIdArray = data.getJSONArray(idAttr);
        JSONArray refNoArray = data.getJSONArray(noAttr);
        if (CollectionsUtil.isNotEmpty(amountDetail)) {
            //遍历金额明细如果有金额为0的合并开票就删掉
            for (int i = 0; i < amountDetail.size(); i++) {
                JSONObject amountDetailObject = amountDetail.getJSONObject(i);
                //发票开票金额
                Long invoiceTotalMoney = amountDetailObject.getLong(InvoiceEnum.TOTAL_MONEY.getAttr());
                //删除开票金额为0的时候
                if(invoiceTotalMoney == 0){
                    JSONArray subRefArray = amountDetailObject.getJSONArray(idAttr);
                    if(!removeArray.contains(amountDetailObject)){
                        removeArray.add(amountDetailObject);
                        num--;
                    }
                    if(subRefArray.size()>0){
                        Long id = subRefArray.getJSONObject(0).getLong(BasicConstant.ID);
                        refIdArray.remove(String.valueOf(id));
                        if(Objects.nonNull(map)) {
                            refNoArray.remove(map.get(id));
                        }
                    }
                }
                if(!isRed){
                    if(invoiceTotalMoney <0){
                        throw new XbbException(InvoiceErrorCodeEnum.API_ERROR_216020);
                    }
                }
            }
        }
        data.put(idAttr,refIdArray);
        data.put(noAttr,refNoArray);
    }

    /**
     * 去除掉没有关联的合同
     * @param amountDetail
     * @param data
     * @param contractMap
     * @param paymentNum
     * @param paymentSheetNum
     */
    public void getRefMapEliminateNoRef(JSONArray amountDetail,JSONObject data,Map<Long,String> contractMap,Integer paymentNum,Integer paymentSheetNum){
        JSONArray refIdArray = data.getJSONArray(InvoiceEnum.CONTRACT_ID.getAttr());
        JSONArray refNoArray = data.getJSONArray(InvoiceEnum.CONTRACT_ID_LINK_TEXT.getAttr());
        Map<Long,List<Long>> refIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        String attr;
        if(paymentNum >0){
            attr = InvoiceEnum.PAYMENT_ID.getAttr();
        }else if(paymentSheetNum >0){
            attr = InvoiceEnum.PAYMENT_SHEET_ID.getAttr();
        }else {
            return;
        }
        if(CollectionsUtil.isNotEmpty(amountDetail)) {
            for (int i = 0; i < amountDetail.size(); i++) {
                JSONObject amountObject = amountDetail.getJSONObject(i);
                JSONObject jsonObject = null;
                if(Objects.nonNull(amountObject)){
                    jsonObject = amountObject.getJSONArray(attr).getJSONObject(0);
                }
                if(Objects.nonNull(jsonObject)) {
                    if (refIdMap.containsKey(jsonObject.getLong(InvoiceEnum.CONTRACT_ID.getSaasAttr()))) {
                        List<Long> idList = refIdMap.get(jsonObject.getLong(InvoiceEnum.CONTRACT_ID.getSaasAttr()));
                        idList.add(jsonObject.getLong(InvoiceEnum.CONTRACT_ID.getSaasAttr()));
                    }else {
                        List<Long> idList = new ArrayList<>();
                        idList.add(jsonObject.getLong(BasicConstant.ID));
                        if(jsonObject.containsKey(InvoiceEnum.CONTRACT_ID.getSaasAttr())){
                            refIdMap.put(jsonObject.getLong(InvoiceEnum.CONTRACT_ID.getSaasAttr()),idList);
                        }
                    }
                }
            }
            JSONArray contractIdArray = data.getJSONArray(InvoiceEnum.CONTRACT_ID.getAttr());
            if(CollectionsUtil.isNotEmpty(contractIdArray)) {
                for (int j = 0; j < contractIdArray.size(); j++) {
                    Long id = contractIdArray.getLong(j);
                    if (refIdMap.size() > 0) {
                        if (!refIdMap.containsKey(id)) {
                            refIdArray.remove(String.valueOf(id));
                            refNoArray.remove(contractMap.get(id));
                            contractMap.remove(id);
                        }
                    }
                }
            }
            data.put(InvoiceEnum.CONTRACT_ID.getAttr(),refIdArray);
            data.put(InvoiceEnum.CONTRACT_ID_LINK_TEXT.getAttr(),refNoArray);
        }
    }







    /**
     * 进项发票，销项发票 提出来的 公共方法 删除时检查 红冲金额
     * 之后对销项发票进行统一改造 会只保留这个方法
     * @param checkRedInvoiceDeletePojo
     * @param idSet
     * @param redNoMapping
     * @param errorDataId
     * @param errorDataNo
     */
    public void checkRedInvoiceDelete(CheckRedInvoiceDeletePojo checkRedInvoiceDeletePojo, Set<Long> idSet, Map<Long,String> redNoMapping, List<Long> errorDataId, List<String> errorDataNo){
        Map<Long,Double> contractOrPurchaseAmountMap = checkRedInvoiceDeletePojo.getContractOrPurchaseAmountMap();
        Map<Long,Double> paymentOrPayPlanAmountMap = checkRedInvoiceDeletePojo.getPaymentOrPayPlanAmountMap();
        Map<Long,Double> paymentSheetOrPaySheetAmountMap = checkRedInvoiceDeletePojo.getPaymentSheetOrPaySheetAmountMap();
        Map<Long,Double> paymentOrPayPlanInvoiceHistoryMap = checkRedInvoiceDeletePojo.getPaymentOrPayPlanInvoiceHistoryMap();
        Map<Long,Double> paymentSheetOrPaySheetInvoiceHistoryMap = checkRedInvoiceDeletePojo.getPaymentSheetOrPaySheetInvoiceHistoryMap();
        Map<Long,Double> contractOrPurchaseInvoiceHistoryMap = checkRedInvoiceDeletePojo.getContractOrPurchaseInvoiceHistoryMap();
        Map<Long,List<Long>> invoiceRefContractOrPurchaseMap = checkRedInvoiceDeletePojo.getInvoiceRefContractOrPurchaseMap();
        Map<Long,List<Long>> invoiceRefPaymentOrPayPlanMap = checkRedInvoiceDeletePojo.getInvoiceRefPaymentOrPayPlanMap();
        Map<Long,List<Long>> invoiceRefPaymentSheetOrPaySheetMap = checkRedInvoiceDeletePojo.getInvoiceRefPaymentSheetOrPaySheetMap();
        Map<Long,Map<Long,Double>> contractOrPurchaseRedMoneyMap = checkRedInvoiceDeletePojo.getContractOrPurchaseRedMoneyMap();
        Map<Long,Map<Long,Double>> paymentOrPayPlanRedMoneyMap = checkRedInvoiceDeletePojo.getPaymentOrPayPlanRedMoneyMap();
        Map<Long,Map<Long,Double>> paymentSheetOrPaySheetRedMoneyMap = checkRedInvoiceDeletePojo.getPaymentSheetOrPaySheetRedMoneyMap();
        //新数据计算可开票金额以及总金额
        if(CollectionsUtil.isNotEmpty(idSet)) {
            for (Long id : idSet) {
                if(Objects.nonNull(invoiceRefContractOrPurchaseMap)) {
                    if (invoiceRefContractOrPurchaseMap.containsKey(id)) {
                        List<Long> contractOrPurchaseIdList = invoiceRefContractOrPurchaseMap.get(id);
                        if (CollectionsUtil.isNotEmpty(contractOrPurchaseIdList)) {
                            for (Long contractOrPurchaseId : contractOrPurchaseIdList) {
                                double contractOrPurchaseInvoiceHistory = contractOrPurchaseInvoiceHistoryMap.getOrDefault(contractOrPurchaseId, 0D);
                                double contractOrPurchaseAmount = contractOrPurchaseAmountMap.getOrDefault(contractOrPurchaseId, 0D);
                                Map<Long,Double> refRedInvoiceMap = contractOrPurchaseRedMoneyMap.getOrDefault(id,new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY));
                                double redInvoiceAmount = refRedInvoiceMap.getOrDefault(contractOrPurchaseId, 0D);
                                //删除红冲发票 根据所关联的业务的可开票的金额 加上 红冲的金额(负的) 如果小于零说明不够开,不允许删除
                                if (Arith.add(Arith.sub(contractOrPurchaseAmount, contractOrPurchaseInvoiceHistory), redInvoiceAmount) < 0) {
                                    errorDataNo.add(redNoMapping.getOrDefault(id, ""));
                                    errorDataId.add(id);
                                    break;
                                }
                            }
                        }
                    }
                }
                if(Objects.nonNull(invoiceRefPaymentOrPayPlanMap)) {
                    if (invoiceRefPaymentOrPayPlanMap.containsKey(id)) {
                        List<Long> paymentOrPayPlanIdList = invoiceRefPaymentOrPayPlanMap.get(id);
                        if(CollectionsUtil.isNotEmpty(paymentOrPayPlanIdList)){
                            for(Long paymentOrPayPlanId : paymentOrPayPlanIdList){
                                double paymentOrPayPlanInvoiceHistory = paymentOrPayPlanInvoiceHistoryMap.getOrDefault(paymentOrPayPlanId,0D);
                                double paymentOrPayPlanAmount = paymentOrPayPlanAmountMap.getOrDefault(paymentOrPayPlanId,0D);
                                Map<Long,Double> refRedInvoiceMap = paymentOrPayPlanRedMoneyMap.getOrDefault(id,new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY));
                                double redInvoiceAmount = refRedInvoiceMap.getOrDefault(paymentOrPayPlanId, 0D);
                                if (Arith.add(Arith.sub(paymentOrPayPlanAmount, paymentOrPayPlanInvoiceHistory), redInvoiceAmount) < 0) {
                                    errorDataNo.add(redNoMapping.getOrDefault(id, ""));
                                    errorDataId.add(id);
                                    break;
                                }
                            }
                        }
                    }
                }
                if(Objects.nonNull(invoiceRefPaymentSheetOrPaySheetMap)){
                    if (invoiceRefPaymentSheetOrPaySheetMap.containsKey(id)) {
                        List<Long> paymentSheetOrPaySheetIdList = invoiceRefPaymentSheetOrPaySheetMap.get(id);
                        if(CollectionsUtil.isNotEmpty(paymentSheetOrPaySheetIdList)){
                            for(Long paymentSheetOrPaySheetId : paymentSheetOrPaySheetIdList){
                                double paymentSheetOrPaySheetInvoiceHistory = paymentSheetOrPaySheetInvoiceHistoryMap.getOrDefault(paymentSheetOrPaySheetId,0D);
                                double paymentSheetOrPaySheetAmount = paymentSheetOrPaySheetAmountMap.getOrDefault(paymentSheetOrPaySheetId,0D);
                                Map<Long,Double> refRedInvoiceMap = paymentSheetOrPaySheetRedMoneyMap.getOrDefault(id,new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY));
                                double redInvoiceAmount = refRedInvoiceMap.getOrDefault(paymentSheetOrPaySheetId, 0D);
                                if (Arith.add(Arith.sub(paymentSheetOrPaySheetAmount, paymentSheetOrPaySheetInvoiceHistory), redInvoiceAmount) < 0) {
                                    errorDataNo.add(redNoMapping.getOrDefault(id, ""));
                                    errorDataId.add(id);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 获取这次删除时返回的金额
     * @param historyMap 关联数据历史开票金额
     * @param deleteChangeMoneyMap 这次删除时删除掉的金额 普通发票
     * @param entityExtMap
     * @param businessType
     * @return
     */
    public List<UpdateDataEntity> deleteInvoiceGetAmount(String corpid,Map<Long,Double> historyMap,Map<Long,Double> deleteChangeMoneyMap,Map<Long,PaasFormDataEntityExt> entityExtMap,Integer businessType) throws XbbException{
        List<UpdateDataEntity> updateDataEntitys = new ArrayList<>();
        Map<String,Double> uuidMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Set<String> uuids = new HashSet<>();
        if(Objects.nonNull(historyMap)) {
            Iterator<Map.Entry<Long, Double>> it = historyMap.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry<Long, Double> entry = it.next();
                Long id = entry.getKey();
                double historyInvoiceAmount = historyMap.getOrDefault(id,0D);
                double deleteChangeMoney = deleteChangeMoneyMap.getOrDefault(id, 0D);
                PaasFormDataEntityExt paasFormDataEntityExt = entityExtMap.get(id);
                if(Objects.nonNull(paasFormDataEntityExt)){
                    JSONObject data = paasFormDataEntityExt.getData();
                    if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE.getCode())){
                        double amount = getDoubleOrDefaultFromFormData(data,PurchaseEnum.TOTAL_MONEY.getAttr(),0D);
                        data.put(PurchaseEnum.INVOICE_AMOUNT.getAttr(),Arith.sub(historyInvoiceAmount,deleteChangeMoney));
                        data.put(PurchaseEnum.UN_INVOICE_AMOUNT.getAttr(),Arith.sub(amount,Arith.sub(historyInvoiceAmount,deleteChangeMoney)));
                    }
                    if(Objects.equals(businessType,XbbRefTypeEnum.PAY_PLAN.getCode())){
                        data.put(PayPlanEnum.INVOICE_AMOUNT.getAttr(),Arith.sub(historyInvoiceAmount,deleteChangeMoney));
                    }
                    if(Objects.equals(businessType,XbbRefTypeEnum.PAY_SHEET.getCode())){
                        data.put(PaySheetEnum.INVOICE_AMOUNT.getAttr(),Arith.sub(historyInvoiceAmount,deleteChangeMoney));
                        uuids.add(paasFormDataEntityExt.getUuid());
                        saasSaveHelp.addMapTwoInvoiceAmount(uuidMap,paasFormDataEntityExt.getUuid(),Arith.sub(historyInvoiceAmount,deleteChangeMoney));
                    }
                    UpdateDataEntity updateEntity = ExplainUtil.getUpdateData(paasFormDataEntityExt.getId(), data, corpid);
                    updateDataEntitys.add(updateEntity);
                }
            }
        }
        if(Objects.equals(businessType,XbbRefTypeEnum.PAY_SHEET.getCode())){
            //更新父付款单
            List<PaasFormDataEntityExt> paySheetEntityExtList = fundHelp.getParentAndChildEsDataListByUuids(IndexTypeEnum.IDX_SAAS_PAYPLAN_SHEET, corpid, uuids);
            if(CollectionsUtil.isNotEmpty(paySheetEntityExtList)) {
                for (PaasFormDataEntityExt paySheetEntityExt : paySheetEntityExtList) {
                    if (Objects.equals(paySheetEntityExt.getAlone(), SheetAloneEnum.PARENT.getCode())) {
                        JSONObject data = paySheetEntityExt.getData();
                        double invoiceAmount = uuidMap.get(paySheetEntityExt.getUuid());
                        data.put(PaySheetEnum.INVOICE_AMOUNT.getAttr(),invoiceAmount);
                        UpdateDataEntity updateEntity = ExplainUtil.getUpdateData(paySheetEntityExt.getId(),data, corpid);
                        updateDataEntitys.add(updateEntity);

                    }
                }
            }
        }
        return updateDataEntitys;
    }

    public InvoiceAmountDetailGetDTO getAmountDetailBySalesInvoiceData(PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException{
        JSONObject data = paasFormDataEntityExt.getData();
        InvoiceAmountDetailGetDTO invoiceAmountDetailGetDTO = new InvoiceAmountDetailGetDTO();
        if(Objects.nonNull(data)){
            Integer isRed = getIntegerOrDefaultFromFormData(data,InvoiceEnum.IS_RED.getAttr(),BasicConstant.ZERO);
            invoiceAmountDetailGetDTO.setIsRed(isRed);
            JSONArray customerJson = data.getJSONArray(InvoiceEnum.CUSTOMER_NAME.getAttr());
            List<Long> supplierIdList = InvoiceCommonHelp.getIdListByJSONArray(customerJson);
            JSONArray contractJson = data.getJSONArray(InvoiceEnum.CONTRACT_ID.getAttr());
            List<Long> contractIdList = InvoiceCommonHelp.getIdListByJSONArray(contractJson);
            JSONArray paymentJson = data.getJSONArray(InvoiceEnum.PAYMENT_ID.getAttr());
            List<Long> paymentIdList = InvoiceCommonHelp.getIdListByJSONArray(paymentJson);
            JSONArray paymentSheetJson = data.getJSONArray(InvoiceEnum.PAYMENT_SHEET_ID.getAttr());
            List<Long> paymentSheetList = InvoiceCommonHelp.getIdListByJSONArray(paymentSheetJson);
            invoiceAmountDetailGetDTO.setCustomerIdList(supplierIdList);
            invoiceAmountDetailGetDTO.setContractIdList(contractIdList);
            invoiceAmountDetailGetDTO.setPaymentIdList(paymentIdList);
            invoiceAmountDetailGetDTO.setPaymentSheetIdList(paymentSheetList);
            invoiceAmountDetailGetDTO.setInvoiceId(paasFormDataEntityExt.getId());
        }
        return invoiceAmountDetailGetDTO;
    }

    /**
     * 详情页面根据发票id获取的详情
     * @param dataId
     * @param corpid
     * @return
     */
    public List<InvoiceAmountDetailDTO> getAmountDetailByInvoiceDataId(Long dataId,String corpid){
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<InvoiceAmountDetailDTO> invoiceAmountDetailDTOList = new ArrayList<>();
        /*param.put("isCancel", isCancel);*/
        param.put("purchaseInvoiceId", dataId);
        param.put("corpid",corpid);
        param.put("del", DelEnum.NORMAL.getDel());
        List<PurchaseInvoiceRelationshipEntity> purchaseInvoiceRelationshipEntities = purchaseInvoiceRelationshipModel.findEntitys(param);
        if(CollectionsUtil.isNotEmpty(purchaseInvoiceRelationshipEntities)){
            for(PurchaseInvoiceRelationshipEntity purchaseInvoiceRelationshipEntity : purchaseInvoiceRelationshipEntities){
                InvoiceAmountDetailDTO invoiceAmountDetailDTO = new InvoiceAmountDetailDTO();
                List<JSONObject> supplierList = new ArrayList<>();
                JSONObject supplierObject = new JSONObject();
                supplierObject.put(BasicConstant.ID,purchaseInvoiceRelationshipEntity.getSupplierId());
                supplierObject.put(BasicConstant.NAME,purchaseInvoiceRelationshipEntity.getSupplierName());
                supplierList.add(supplierObject);
                invoiceAmountDetailDTO.setSupplier(supplierList);
                if(!Objects.equals(purchaseInvoiceRelationshipEntity.getPurchaseId(),0L)) {
                    List<JSONObject> purchaseList = new ArrayList<>();
                    JSONObject purchaseObject = new JSONObject();
                    purchaseObject.put(BasicConstant.ID, purchaseInvoiceRelationshipEntity.getPurchaseId());
                    purchaseObject.put(BasicConstant.NAME, purchaseInvoiceRelationshipEntity.getPurchaseNo());
                    purchaseList.add(purchaseObject);
                    invoiceAmountDetailDTO.setPurchase(purchaseList);
                }
                if(!Objects.equals(purchaseInvoiceRelationshipEntity.getPayPlanId(),0L)) {
                    List<JSONObject> payPlanList = new ArrayList<>();
                    JSONObject payPlanObject = new JSONObject();
                    payPlanObject.put(BasicConstant.ID, purchaseInvoiceRelationshipEntity.getPayPlanId());
                    payPlanObject.put(BasicConstant.NAME, purchaseInvoiceRelationshipEntity.getPayPlanNo());
                    payPlanList.add(payPlanObject);
                    invoiceAmountDetailDTO.setPayPlan(payPlanList);
                }
                if(!Objects.equals(purchaseInvoiceRelationshipEntity.getPaySheetId(),0L)) {
                    List<JSONObject> paySheetList = new ArrayList<>();
                    JSONObject paySheetObject = new JSONObject();
                    paySheetObject.put(BasicConstant.ID, purchaseInvoiceRelationshipEntity.getPaySheetId());
                    paySheetObject.put(BasicConstant.NAME, purchaseInvoiceRelationshipEntity.getPaySheetNo());
                    paySheetList.add(paySheetObject);
                    invoiceAmountDetailDTO.setPaySheet(paySheetList);
                }
                invoiceAmountDetailDTO.setInvoiceAmount(purchaseInvoiceRelationshipEntity.getMoney());
                invoiceAmountDetailDTOList.add(invoiceAmountDetailDTO);
            }
        }
        return invoiceAmountDetailDTOList;
    }

    /**
     * 详情页面根据发票id获取的详情
     * @param dataId
     * @param corpid
     * @return
     */
    public List<InvoiceAmountDetailDTO> getAmountDetailBySalesInvoiceDataId(Long dataId,String corpid){
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<InvoiceAmountDetailDTO> invoiceAmountDetailDTOList = new ArrayList<>();
        param.put("invoiceId", dataId);
        param.put("corpid",corpid);
        param.put("del", DelEnum.NORMAL.getDel());
        List<InvoiceRelationshipEntity> invoiceRelationshipEntities = invoiceRelationshipModel.findEntitys(param);
        if(CollectionsUtil.isNotEmpty(invoiceRelationshipEntities)){
            for(InvoiceRelationshipEntity invoiceRelationshipEntity : invoiceRelationshipEntities){
                InvoiceAmountDetailDTO invoiceAmountDetailDTO = new InvoiceAmountDetailDTO();
                List<JSONObject> customerList = new ArrayList<>();
                JSONObject customerObject = new JSONObject();
                customerObject.put(BasicConstant.ID,invoiceRelationshipEntity.getCustomerId());
                customerObject.put(BasicConstant.NAME,invoiceRelationshipEntity.getCustomerName());
                customerList.add(customerObject);
                invoiceAmountDetailDTO.setCustomer(customerList);
                if(!Objects.equals(invoiceRelationshipEntity.getContractId(),0L)) {
                    List<JSONObject> contractList = new ArrayList<>();
                    JSONObject contractObject = new JSONObject();
                    contractObject.put(BasicConstant.ID, invoiceRelationshipEntity.getContractId());
                    contractObject.put(BasicConstant.NAME, invoiceRelationshipEntity.getContractNo());
                    contractList.add(contractObject);
                    invoiceAmountDetailDTO.setContract(contractList);
                }
                if(!Objects.equals(invoiceRelationshipEntity.getPaymentId(),0L)) {
                    List<JSONObject> paymentList = new ArrayList<>();
                    JSONObject paymentObject = new JSONObject();
                    paymentObject.put(BasicConstant.ID, invoiceRelationshipEntity.getPaymentId());
                    paymentObject.put(BasicConstant.NAME, invoiceRelationshipEntity.getPaymentNo());
                    paymentList.add(paymentObject);
                    invoiceAmountDetailDTO.setPayment(paymentList);
                }
                if(!Objects.equals(invoiceRelationshipEntity.getPaymentSheetId(),0L)) {
                    List<JSONObject> paymentSheetList = new ArrayList<>();
                    JSONObject paymentSheetObject = new JSONObject();
                    paymentSheetObject.put(BasicConstant.ID, invoiceRelationshipEntity.getPaymentSheetId());
                    paymentSheetObject.put(BasicConstant.NAME, invoiceRelationshipEntity.getPaymentSheetNo());
                    paymentSheetList.add(paymentSheetObject);
                    invoiceAmountDetailDTO.setPaymentSheet(paymentSheetList);
                }
                invoiceAmountDetailDTO.setInvoiceAmount(invoiceRelationshipEntity.getMoney());
                invoiceAmountDetailDTOList.add(invoiceAmountDetailDTO);
            }
        }
        return invoiceAmountDetailDTOList;
    }


    /**
     * 销项发票审批时查询每条记录的最大可添加金额
     * 下面是具体的计算每条记录的最大可添加金额（1）合同的直接读未开票金额
     *                                 （2）回款计划/回款单的则取 （回款计划金额-回款计划开票金额）/（回款单金额-回款单开票金额）与合同的未开票金额取最小值
     *                                 （3）如果对回款单/回款计划新建销项发票时候，如果合同为空，则开票金额等于回款计划金额-回款计划开票金额）/（回款单金额-回款单开票金额）
     *
     * @param corpid 公司id
     * @param data 审批表中的data值
     * @param xbbRefTypeEnum 业务类型
     * @param amountObj 审批表中的saas_need_pojo信息
     * @param linkId 需要查询得关联id
     * @return
     */
    private void invoiceMaxAmount(String corpid, JSONObject data, XbbRefTypeEnum xbbRefTypeEnum,JSONObject amountObj, Long linkId) throws XbbException{
        //首先需要把合同的未开票金额跟合同id组成一个Map
        JSONArray contractIdArray = data.getJSONArray(InvoiceEnum.CONTRACT_ID.getAttr());
        HashMap<Long, Double> hashMap = new HashMap<>();
        if (Objects.nonNull(contractIdArray)) {
            //合同id数组可能为空，比如对预收款
            BoolQueryBuilder contractBoolQueryBuilder = boolQuery();
            contractBoolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
            contractBoolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
            contractBoolQueryBuilder.filter(termsQuery("id", contractIdArray));
            XbbAggregatedPage contractAggregatedPage = esHelper.findByPage(IndexTypeEnum.IDX_SAAS_CONTRACT, contractBoolQueryBuilder, PaasFormDataEntityExt.class, null, PaasConstant.ES_COMMON_PAGE , PaasConstant.ES_MAX_PAGE_SIZE, null);
            if (Objects.nonNull(contractAggregatedPage)) {
                List<PaasFormDataEntityExt> contractPaasFormDataEntityExts = contractAggregatedPage.getContent();
                for (PaasFormDataEntity paasFormDataEntity : contractPaasFormDataEntityExts) {
                    double contractUnInvoiceMoney = paasFormDataEntity.getData().getDouble(ContractEnum.UN_INVOICE_AMOUNT.getAttr());
                    hashMap.put(paasFormDataEntity.getId(), contractUnInvoiceMoney);
                }
            }
        }

        //下面是具体到业务的一些方法
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termsQuery("flowStatus", FlowStatusEnum.getStatisticType()));
        IndexTypeEnum indexTypeEnum = null;
        if (xbbRefTypeEnum.equals(XbbRefTypeEnum.PAYMENT)) {
            boolQueryBuilder.filter(termQuery("id", linkId));
            indexTypeEnum = IndexTypeEnum.IDX_SAAS_PAYMENT;
        }else if (xbbRefTypeEnum.equals(XbbRefTypeEnum.PAYMENT_SHEET)) {
            boolQueryBuilder.filter(termQuery("id", linkId));
            indexTypeEnum = IndexTypeEnum.IDX_SAAS_PAYMENT_SHEET;
        }else if (xbbRefTypeEnum.equals(XbbRefTypeEnum.CONTRACT)) {
            boolQueryBuilder.filter(termQuery("id", linkId));
            indexTypeEnum = IndexTypeEnum.IDX_SAAS_CONTRACT;
        }
        XbbAggregatedPage aggregatedPage = esHelper.findByPage(indexTypeEnum, boolQueryBuilder, PaasFormDataEntityExt.class, null, PaasConstant.ES_COMMON_PAGE , PaasConstant.ES_MAX_PAGE_SIZE, null);
        if (Objects.nonNull(aggregatedPage)) {
            List<PaasFormDataEntityExt> paasFormDataEntityExts = aggregatedPage.getContent();
            //需要对结果进行不同的处理 (1)合同只需要直接取未开票金额就好 (2)老回款计划（现在应收款）/回款单的话需要总金额 - 已开票金额
            for (PaasFormDataEntity paasFormDataEntity : paasFormDataEntityExts) {
                JSONObject jsonObject = paasFormDataEntity.getData();
                double subInvoiceMoney = BasicConstant.ZERO_DOUBLE;
                double contractUnInvoiceMoney = BasicConstant.ZERO_DOUBLE;
                double maxInvoiceMoney = BasicConstant.ZERO_DOUBLE;
                if (xbbRefTypeEnum.equals(XbbRefTypeEnum.PAYMENT)) {
                    double totalMoney = FastJsonHelper.getDoubleOrDefaultFromFormData(jsonObject, PaymentEnum.AMOUNT.getAttr(), BasicConstant.ZERO_DOUBLE);
                    double paymentInvoiceMoney = FastJsonHelper.getDoubleOrDefaultFromFormData(jsonObject, PaymentEnum.INVOICE_AMOUNT.getAttr(), BasicConstant.ZERO_DOUBLE);
                    Integer contractId = FastJsonHelper.getIntegerOrDefaultFromFormData(jsonObject, PaymentEnum.CONTRACT.getAttr(), BasicConstant.ZERO);
                    subInvoiceMoney = Arith.sub(totalMoney, paymentInvoiceMoney);
                    if (Objects.isNull(contractIdArray)) {
                        maxInvoiceMoney = subInvoiceMoney;
                    }else {
                        contractUnInvoiceMoney = hashMap.get(Long.valueOf(String.valueOf(contractId)));
                        maxInvoiceMoney = Collections.min(Arrays.asList(subInvoiceMoney, contractUnInvoiceMoney));
                    }
                }else if (xbbRefTypeEnum.equals(XbbRefTypeEnum.PAYMENT_SHEET)) {
                    double totalMoney = FastJsonHelper.getDoubleOrDefaultFromFormData(jsonObject, PaymentSheetEnum.AMOUNT.getAttr(), BasicConstant.ZERO_DOUBLE);
                    double totolMoneySen = FastJsonHelper.getDoubleOrDefaultFromFormData(jsonObject, PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr(), BasicConstant.ZERO_DOUBLE);
                    double paymentSheetInvoiceMoney = FastJsonHelper.getDoubleOrDefaultFromFormData(jsonObject, PaymentSheetEnum.INVOICE_AMOUNT.getAttr(), BasicConstant.ZERO_DOUBLE);
                    if (totalMoney <= BasicConstant.ZERO_DOUBLE) {
                        subInvoiceMoney = Arith.sub(totolMoneySen, paymentSheetInvoiceMoney);
                    }else {
                        subInvoiceMoney = Arith.sub(totalMoney, paymentSheetInvoiceMoney);
                    }
                    if (Objects.isNull(contractIdArray)) {
                        maxInvoiceMoney = subInvoiceMoney;
                    }else {
                        JSONArray contractCurrentIdArray =  jsonObject.getJSONArray(PaymentSheetEnum.CONTRACT.getAttr());
                        contractUnInvoiceMoney = hashMap.get(Long.valueOf(String.valueOf(contractCurrentIdArray.get(0))));
                        maxInvoiceMoney = Collections.min(Arrays.asList(subInvoiceMoney, contractUnInvoiceMoney));
                    }
                }else if (xbbRefTypeEnum.equals(XbbRefTypeEnum.CONTRACT)) {
                    double unInvoiceAmount = FastJsonHelper.getDoubleOrDefaultFromFormData(jsonObject, ContractEnum.UN_INVOICE_AMOUNT.getAttr(), BasicConstant.ZERO_DOUBLE);
                    maxInvoiceMoney = unInvoiceAmount;
                }
                amountObj.put(InvoiceConstant.MAX_INVOICE_AMOUNT, maxInvoiceMoney);
            }
        }
    }

    /**
     * 进项发票审批时查询每条记录的最大可添加金额
     * 下面是具体的计算每条记录的最大可添加金额（1）采购合同的直接读未开票金额
     *                                 （2）付款计划/付款单的读取 （付款计划金额-付款计划开票金额）/（付款单金额-付款单开票金额）与采购合同的未开票金额取最小值
     *                                 (3)如果付款计划/付款单新建进项发票时候，如果采购合同为空，则开票金额等于付款计划金额-付款计划开票金额）/（付款单金额-付款单开票金额）
     *
     * @param corpid 公司id
     * @param data 审批表中的data值
     * @param xbbRefTypeEnum 业务类型
     * @param amountObj 审批表中的saas_need_pojo信息
     * @param linkId 需要查询得关联id
     * @throws XbbException
     */
    private void purchaseInvoiceMaxMoney(String corpid, JSONObject data, XbbRefTypeEnum xbbRefTypeEnum,JSONObject amountObj, Long linkId) throws XbbException{
        //首先需要把采购合同的未开票金额跟合同id组成一个Map
        JSONArray purchaseContractIdArray = data.getJSONArray(PurchaseEnum.SUPPLIER_ID.getAttr());
        HashMap<Long, Double> hashMap = new HashMap<>();
        if (Objects.nonNull(purchaseContractIdArray)) {
            BoolQueryBuilder purchaseContractBoolQueryBuilder = boolQuery();
            purchaseContractBoolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
            purchaseContractBoolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
            purchaseContractBoolQueryBuilder.filter(termsQuery("id", purchaseContractIdArray));
            XbbAggregatedPage purchaseContractAggregatedPage = esHelper.findByPage(IndexTypeEnum.IDX_SAAS_PURCHASE, purchaseContractBoolQueryBuilder, PaasFormDataEntityExt.class, null, PaasConstant.ES_COMMON_PAGE , PaasConstant.ES_MAX_PAGE_SIZE, null);
            if (Objects.nonNull(purchaseContractAggregatedPage)) {
                List<PaasFormDataEntityExt> purchaseContractPaasFormDataEntityExts = purchaseContractAggregatedPage.getContent();
                for (PaasFormDataEntity paasFormDataEntity : purchaseContractPaasFormDataEntityExts) {
                    double purchaseContractUnInvoiceMoney = paasFormDataEntity.getData().getDouble(PurchaseEnum.UN_INVOICE_AMOUNT.getAttr());
                    hashMap.put(paasFormDataEntity.getId(), purchaseContractUnInvoiceMoney);
                }
            }
        }

        //下面是具体到业务的一些方法
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termsQuery("flowStatus", FlowStatusEnum.getStatisticType()));
        IndexTypeEnum indexTypeEnum = null;
        if (xbbRefTypeEnum.equals(XbbRefTypeEnum.PAY_PLAN)) {
            boolQueryBuilder.filter(termQuery("id", linkId));
            indexTypeEnum = IndexTypeEnum.IDX_SAAS_PAY_PLAN;
        }else if (xbbRefTypeEnum.equals(XbbRefTypeEnum.PAY_SHEET)) {
            boolQueryBuilder.filter(termQuery("id", linkId));
            indexTypeEnum = IndexTypeEnum.IDX_SAAS_PAYPLAN_SHEET;
        }else if (xbbRefTypeEnum.equals(XbbRefTypeEnum.PURCHASE)) {
            boolQueryBuilder.filter(termQuery("id", linkId));
            indexTypeEnum = IndexTypeEnum.IDX_SAAS_PURCHASE;
        }
        XbbAggregatedPage aggregatedPage = esHelper.findByPage(indexTypeEnum, boolQueryBuilder, PaasFormDataEntityExt.class, null, PaasConstant.ES_COMMON_PAGE , PaasConstant.ES_MAX_PAGE_SIZE, null);
        if (Objects.nonNull(aggregatedPage)) {
            List<PaasFormDataEntityExt> paasFormDataEntityExts = aggregatedPage.getContent();
            //需要对结果进行不同的处理 (1)采购合同只需要直接取未开票金额就好 (2)付款计划/付款单的话需要总金额 - 已开票金额
            for (PaasFormDataEntity paasFormDataEntity : paasFormDataEntityExts) {
                JSONObject jsonObject = paasFormDataEntity.getData();
                double subInvoiceMoney = BasicConstant.ZERO_DOUBLE;
                double purchaseContractUnInvoiceMoney = BasicConstant.ZERO_DOUBLE;
                double maxInvoiceMoney = BasicConstant.ZERO_DOUBLE;
                if (xbbRefTypeEnum.equals(XbbRefTypeEnum.PAY_PLAN)) {
                    double totalMoney = FastJsonHelper.getDoubleOrDefaultFromFormData(jsonObject, PayPlanEnum.AMOUNT.getAttr(), BasicConstant.ZERO_DOUBLE);
                    double payPlanInvoiceMoney = FastJsonHelper.getDoubleOrDefaultFromFormData(jsonObject, PayPlanEnum.INVOICE_AMOUNT.getAttr(), BasicConstant.ZERO_DOUBLE);
                    Integer purchaseId = FastJsonHelper.getIntegerOrDefaultFromFormData(jsonObject, PayPlanEnum.LINK_PURCHASE.getAttr(), BasicConstant.ZERO);
                    subInvoiceMoney = Arith.sub(totalMoney, payPlanInvoiceMoney);
                    if (Objects.isNull(purchaseContractIdArray)) {
                        maxInvoiceMoney = subInvoiceMoney;
                    }else {
                        purchaseContractUnInvoiceMoney = hashMap.get(Long.valueOf(String.valueOf(purchaseId)));
                        maxInvoiceMoney = Collections.min(Arrays.asList(subInvoiceMoney, purchaseContractUnInvoiceMoney));
                    }
                }else if (xbbRefTypeEnum.equals(XbbRefTypeEnum.PAY_SHEET)) {
                    double totalMoney = FastJsonHelper.getDoubleOrDefaultFromFormData(jsonObject, PaySheetEnum.AMOUNT.getAttr(), BasicConstant.ZERO_DOUBLE);
                    double totolMoneySen = FastJsonHelper.getDoubleOrDefaultFromFormData(jsonObject, PaySheetEnum.WRITE_OFF_AMOUNT.getAttr(), BasicConstant.ZERO_DOUBLE);
                    double paySheetInvoiceMoney = FastJsonHelper.getDoubleOrDefaultFromFormData(jsonObject, PaySheetEnum.INVOICE_AMOUNT.getAttr(), BasicConstant.ZERO_DOUBLE);
                    if (totalMoney <= BasicConstant.ZERO_DOUBLE) {
                        subInvoiceMoney = Arith.sub(totolMoneySen, paySheetInvoiceMoney);
                    }else {
                        subInvoiceMoney = Arith.sub(totalMoney, paySheetInvoiceMoney);
                    }
                    if (Objects.isNull(purchaseContractIdArray)) {
                        maxInvoiceMoney = subInvoiceMoney;
                    }else {
                        JSONArray contractCurrentIdArray =  jsonObject.getJSONArray(PaySheetEnum.LINK_PURCHASE.getAttr());
                        purchaseContractUnInvoiceMoney = hashMap.get(Long.valueOf(String.valueOf(contractCurrentIdArray.get(0))));
                        maxInvoiceMoney = Collections.min(Arrays.asList(subInvoiceMoney, purchaseContractUnInvoiceMoney));
                    }
                }else if (xbbRefTypeEnum.equals(XbbRefTypeEnum.PURCHASE)) {
                    double unPurchaseInvoiceAmount = FastJsonHelper.getDoubleOrDefaultFromFormData(jsonObject, PurchaseEnum.UN_INVOICE_AMOUNT.getAttr(), BasicConstant.ZERO_DOUBLE);
                    maxInvoiceMoney = unPurchaseInvoiceAmount;
                }
                amountObj.put(InvoiceConstant.MAX_INVOICE_AMOUNT, maxInvoiceMoney);
            }
        }

    }

    /**
     * 保证接口测试时不报错检验
     */
    public void checkApiResultSafe(PaasFormDataEntity paasFormDataEntity){
        if(Objects.nonNull(paasFormDataEntity)){
            JSONObject data = paasFormDataEntity.getData();
            JSONArray customerInvoice = data.getJSONArray(InvoiceEnum.CUSTOMER_INVOICE.getAttr());
            if(CollectionsUtil.isEmpty(customerInvoice)){
                JSONArray jsonArray = new JSONArray();
                JSONObject jsonObject = new JSONObject();
                jsonObject.put(CustomerInvoiceEnum.TITLE.getAttr(),"");
                jsonObject.put(CustomerInvoiceEnum.TAXPAYER_NO.getAttr(),"");
                jsonObject.put(CustomerInvoiceEnum.REGISTERED_PHONE.getAttr(),"");
                jsonObject.put(CustomerInvoiceEnum.INVOICE_ADDRESS.getAttr(),"");
                jsonObject.put(CustomerInvoiceEnum.BANK.getAttr(),"");
                jsonObject.put(CustomerInvoiceEnum.ACCOUNT.getAttr(),"");
                jsonArray.add(jsonObject);
                data.put(InvoiceEnum.CUSTOMER_INVOICE.getAttr(),jsonArray);
            }
            JSONArray customerExpress = data.getJSONArray(InvoiceEnum.CUSTOMER_EXPRESS.getAttr());
            if(CollectionsUtil.isEmpty(customerExpress)){
                JSONArray jsonArray = new JSONArray();
                JSONObject jsonObject = new JSONObject();
                jsonObject.put(CustomerExpressEnum.NAME.getAttr(),"");
                jsonObject.put(CustomerExpressEnum.CONTACT.getAttr(),"");
                jsonObject.put(CustomerExpressEnum.PHONE.getAttr(),"");
                jsonObject.put(CustomerExpressEnum.ZIP_CODE.getAttr(),"");
                JSONObject address = new JSONObject();
                address.put(AddressEnum.PROVINCE.getAlias(),"");
                address.put(AddressEnum.CITY.getAlias(),"");
                address.put(AddressEnum.DISTRICT.getAlias(),"");
                address.put(AddressEnum.ADDRESS.getAlias(),"");
                jsonObject.put(CustomerExpressEnum.ADDRESS.getAttr(),address);
                jsonArray.add(jsonObject);
                data.put(InvoiceEnum.CUSTOMER_EXPRESS.getAttr(),jsonArray);
            }
        }
    }

    public void saveCustomerInvoiceAndExpress(String corpid,Long customerId,String creatorId,String loginUserName,JSONArray customerInvoice,JSONArray customerExpress) throws XbbException{
        invoiceHelp.saveCustomerInvoiceAndExpress(corpid, customerId, creatorId, loginUserName, customerInvoice, customerExpress);
    }

    public Boolean checkContractOrPurchaseInvoice(PaasFormDataEntityExt paasFormDataEntityExt,String corpid,RedundantTemplateTypeEnum redundantTemplateTypeEnum) throws XbbException {
        Boolean contractOrPurchaseCanInvoiceFlag = true;
        Map<Long,Double> contractOrPurchaseInvoiceAmount = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid",corpid);
        param.put("del",BasicConstant.ZERO);
        param.put("isCancel",BasicConstant.ZERO);
        if(Objects.equals(redundantTemplateTypeEnum, RedundantTemplateTypeEnum.PAYMENT) || Objects.equals(redundantTemplateTypeEnum,RedundantTemplateTypeEnum.PAYMENT_SHEET)){
            JSONObject data = paasFormDataEntityExt.getData();
            JSONArray contractArray = new JSONArray();
            if(Objects.equals(redundantTemplateTypeEnum, RedundantTemplateTypeEnum.PAYMENT)){
                long contractId = data.getLongValue(PaymentEnum.CONTRACT.getAttr());
                contractArray.add(contractId);
            }else if(Objects.equals(redundantTemplateTypeEnum,RedundantTemplateTypeEnum.PAYMENT_SHEET)){
                contractArray = data.getJSONArray(PaymentSheetEnum.CONTRACT.getAttr());
            }
            if(CollectionsUtil.isNotEmpty(contractArray)) {
                List<ContractEntityExt> contractEntityExtList = contractModel.findEntitysByIdIn(corpid, BasicConstant.ZERO, contractArray.toJavaList(Long.class));
                param.put("contractIdIn", contractArray.toJavaList(Long.class));
                List<InvoiceRelationshipEntity> invoiceRelationshipEntities = invoiceRelationshipModel.findEntitys(param);
                if (CollectionsUtil.isNotEmpty(invoiceRelationshipEntities)) {
                    for (InvoiceRelationshipEntity invoiceRelationshipEntity : invoiceRelationshipEntities) {
                        saasSaveHelp.addMapNormal(contractOrPurchaseInvoiceAmount, invoiceRelationshipEntity.getContractId(), invoiceRelationshipEntity.getMoney());
                    }
                }
                if (CollectionsUtil.isNotEmpty(contractEntityExtList)) {
                    for (ContractEntityExt contractEntityExt : contractEntityExtList) {
                        double invoiceAmount = contractOrPurchaseInvoiceAmount.getOrDefault(contractEntityExt.getId(),0D);
                        JSONObject contractObject = contractEntityExt.getData();
                        double amount = getDoubleOrDefaultFromFormData(contractObject, ContractEnum.AMOUNT.getAttr(),0D);
                        if(amount <= invoiceAmount){
                            contractOrPurchaseCanInvoiceFlag = false;
                        }
                    }
                }
            }
        }else if(Objects.equals(redundantTemplateTypeEnum, RedundantTemplateTypeEnum.PAY_PLAN) || Objects.equals(redundantTemplateTypeEnum,RedundantTemplateTypeEnum.PAY_SHEET)){
            JSONObject data = paasFormDataEntityExt.getData();
            JSONArray purchaseArray = new JSONArray();
            if(Objects.equals(redundantTemplateTypeEnum, RedundantTemplateTypeEnum.PAY_PLAN)){
                long purchaseId = data.getLongValue(PayPlanEnum.LINK_PURCHASE.getAttr());
                purchaseArray.add(purchaseId);
            }else if(Objects.equals(redundantTemplateTypeEnum,RedundantTemplateTypeEnum.PAY_SHEET)){
                purchaseArray = data.getJSONArray(PaySheetEnum.LINK_PURCHASE.getAttr());
            }
            if(CollectionsUtil.isNotEmpty(purchaseArray)) {
                List<PurchaseEntityExt> purchaseEntityExtList = purchaseModel.getPurchaseListByIdIn(corpid, purchaseArray.toJavaList(Long.class));
                param.put("purchaseIdIn", purchaseArray.toJavaList(Long.class));
                List<PurchaseInvoiceRelationshipEntity> purchaseInvoiceRelationshipEntities = purchaseInvoiceRelationshipModel.findEntitys(param);
                if (CollectionsUtil.isNotEmpty(purchaseInvoiceRelationshipEntities)) {
                    for (PurchaseInvoiceRelationshipEntity purchaseInvoiceRelationshipEntity : purchaseInvoiceRelationshipEntities) {
                        saasSaveHelp.addMapNormal(contractOrPurchaseInvoiceAmount, purchaseInvoiceRelationshipEntity.getPurchaseId(), purchaseInvoiceRelationshipEntity.getMoney());
                    }
                }
                if (CollectionsUtil.isNotEmpty(purchaseEntityExtList)) {
                    for (PurchaseEntityExt purchaseEntityExt : purchaseEntityExtList) {
                        double invoiceAmount = contractOrPurchaseInvoiceAmount.getOrDefault(purchaseEntityExt.getId(),0D);
                        JSONObject purchaseObject = purchaseEntityExt.getData();
                        double amount = getDoubleOrDefaultFromFormData(purchaseObject,PurchaseEnum.TOTAL_MONEY.getAttr(),0D);
                        if(amount <= invoiceAmount){
                            contractOrPurchaseCanInvoiceFlag = false;
                        }
                    }
                }
            }
        }
        return contractOrPurchaseCanInvoiceFlag;
    }

    public void getUpdateDataBySalesInvoice(FormDataUpdateGetDTO formDataUpdateGetDTO,ButtonGetDTO buttonGetDTO, SaasSpecialParamPojo saasSpecialParamPojo, PaasFormDataEntityExt formData,JSONObject result,List<FieldAttrEntity> explains) throws XbbException{
        InvoiceAmountDetailGetDTO invoiceAmountDetailGetDTO = getAmountDetailBySalesInvoiceData(formData);
        String corpid = null;
        if(formDataUpdateGetDTO != null) {
            corpid = formDataUpdateGetDTO.getCorpid();
            BeanUtil.copyProperties(formDataUpdateGetDTO, invoiceAmountDetailGetDTO);
        }else {
            corpid = buttonGetDTO.getCorpid();
            BeanUtil.copyProperties(buttonGetDTO, invoiceAmountDetailGetDTO);
        }
        invoiceAmountDetailGetDTO.setIsEdit(BasicConstant.ONE);
        JSONObject data = formData.getData();
        JSONArray originObject = data.getJSONArray(InvoiceEnum.ORIGIN_ID.getAttr());
        Long originId = 0L;
        if(Objects.nonNull(originObject)){
            originId = originObject.getJSONObject(BasicConstant.ZERO).getLong(BasicConstant.ID);
        }

        if ( Objects.nonNull(saasSpecialParamPojo) ) {
            //从红冲页过来formRed 会置成1
            Integer fromRed = saasSpecialParamPojo.getFromRed();
            if(Objects.isNull(fromRed)){
                fromRed = BasicConstant.ZERO;
            }
            invoiceAmountDetailGetDTO.setFormRed(fromRed);
            //如果是红冲按钮过来的就把编辑置为0
            if(Objects.equals(fromRed,BasicConstant.ONE)) {
                invoiceAmountDetailGetDTO.setIsEdit(BasicConstant.ZERO);
            }
        }
        if(originId > 0L){
            invoiceAmountDetailGetDTO.setFormRed(BasicConstant.ONE);
        }
        InvoiceAmountDetailVO invoiceAmountDetailVO = invoiceService.getInvoiceAmountDetail(invoiceAmountDetailGetDTO);
        if(Objects.equals(invoiceAmountDetailGetDTO.getIsEdit(),BasicConstant.ONE) && Objects.equals(invoiceAmountDetailGetDTO.getIsRed(),BasicConstant.ONE)){
            if (Objects.nonNull(result)) {
                double invoiceAmount = result.getDouble(InvoiceEnum.TOTAL_MONEY.getAttr());
                result.put(InvoiceEnum.TOTAL_MONEY.getAttr(), -invoiceAmount);
            }
        }
        JSONArray amountDetail = JSONArray.parseArray(JSONArray.toJSONString(invoiceAmountDetailVO.getAmountDetail()));
        JSONArray paymentSheetArray = data.getJSONArray(InvoiceEnum.PAYMENT_SHEET_ID.getAttr());
        List<Long> paymentSheetList = new ArrayList<>();
        if(CollectionsUtil.isNotEmpty(paymentSheetArray)){
            for(int i=0;i<paymentSheetArray.size();i++){
                JSONObject paymentSheetObject = paymentSheetArray.getJSONObject(i);
                paymentSheetList.add(paymentSheetObject.getLong(BasicConstant.ID));
            }
            Map<Long,String> paymentSheetTypeMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put("corpid",corpid);
            map.put("idIn",paymentSheetList);
            map.put("del", BasicConstant.ZERO);
            List<PaymentSheetEntityExt> paySheetEntityList = paymentSheetModel.findEntitys(map);
            paySheetEntityList.forEach(item -> {
                JSONObject jsonObject = item.getData();
                String paymentSheetType = jsonObject.getString(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr());
                paymentSheetTypeMap.put(item.getId(),paymentSheetType);
            });
            for(int i=0;i<paymentSheetArray.size();i++){
                JSONObject paymentSheetObject = paymentSheetArray.getJSONObject(i);
                String paySheetType = paymentSheetTypeMap.getOrDefault(paymentSheetObject.getLong(BasicConstant.ID),"");
                paymentSheetObject.put(InvoiceConstant.PAYMENT_SHEET_TYPE,paySheetType);
            }
        }
        result.put(PaasConstant.AMOUNTDETAIL, amountDetail);
        if(Objects.equals(invoiceAmountDetailGetDTO.getIsRed(),BasicConstant.ONE) || Objects.equals(invoiceAmountDetailGetDTO.getFormRed(),BasicConstant.ONE)){
            explains.forEach(fieldAttrEntity -> {
                if(Objects.equals(InvoiceEnum.PAYMENT_RELATIONSHIP.getAttr(),fieldAttrEntity.getAttr())
                        || Objects.equals(InvoiceEnum.CONTRACT_ID.getAttr(),fieldAttrEntity.getAttr())
                        || Objects.equals(InvoiceEnum.PAYMENT_ID.getAttr(),fieldAttrEntity.getAttr())
                        || Objects.equals(InvoiceEnum.PAYMENT_SHEET_ID.getAttr(),fieldAttrEntity.getAttr())){
                    fieldAttrEntity.setEditable(0);
                }
            });
        }
        fundHelp.setInvoiceNotEditToExplain(explains,invoiceAmountDetailGetDTO.getFormRed(),invoiceAmountDetailGetDTO.getIsRed(),XbbRefTypeEnum.INVOICE.getCode());
    }

    public void getUpdateDataByPurchaseInvoice(FormDataUpdateGetDTO formDataUpdateGetDTO,ButtonGetDTO buttonGetDTO, SaasSpecialParamPojo saasSpecialParamPojo, PaasFormDataEntityExt formData,JSONObject result,List<FieldAttrEntity> explains) throws XbbException{
        PurchaseInvoiceAmountDetailGetDTO purchaseInvoiceAmountDetailGetDTO = InvoiceCommonHelp.getAmountDetailByInvoiceData(formData);
        String corpid = null;
        if(formDataUpdateGetDTO != null) {
            corpid = formDataUpdateGetDTO.getCorpid();
            BeanUtil.copyProperties(formDataUpdateGetDTO, purchaseInvoiceAmountDetailGetDTO);
        }else {
            corpid = buttonGetDTO.getCorpid();
            BeanUtil.copyProperties(buttonGetDTO, purchaseInvoiceAmountDetailGetDTO);
        }
        purchaseInvoiceAmountDetailGetDTO.setIsEdit(BasicConstant.ONE);
        JSONObject data = formData.getData();
        JSONArray originObject = data.getJSONArray(PurchaseInvoiceEnum.ORIGIN_ID.getAttr());
        Long originId = 0L;
        if(Objects.nonNull(originObject)){
            originId = originObject.getJSONObject(BasicConstant.ZERO).getLong(BasicConstant.ID);
        }

        if (Objects.nonNull(saasSpecialParamPojo)) {
            //从红冲页过来formRed 会置成1
            Integer fromRed = saasSpecialParamPojo.getFromRed();
            if(Objects.isNull(fromRed)){
                fromRed = BasicConstant.ZERO;
            }
            purchaseInvoiceAmountDetailGetDTO.setFormRed(fromRed);
            //如果是红冲按钮过来的就把编辑置为0
            if(Objects.equals(fromRed,BasicConstant.ONE)) {
                purchaseInvoiceAmountDetailGetDTO.setIsEdit(BasicConstant.ZERO);
            }
        }
        if(originId > 0L){
            purchaseInvoiceAmountDetailGetDTO.setFormRed(BasicConstant.ONE);
        }
        PurchaseInvoiceAmountDetailVO purchaseInvoiceAmountDetailVO = purchaseInvoiceService.getPurchaseInvoiceAmountDetail(purchaseInvoiceAmountDetailGetDTO);
        if(Objects.equals(purchaseInvoiceAmountDetailGetDTO.getIsEdit(),BasicConstant.ONE) && Objects.equals(purchaseInvoiceAmountDetailGetDTO.getIsRed(),BasicConstant.ONE)){
            if (Objects.nonNull(result)) {
                double invoiceAmount = result.getDouble(PurchaseInvoiceEnum.TOTAL_MONEY.getAttr());
                result.put(PurchaseInvoiceEnum.TOTAL_MONEY.getAttr(), -invoiceAmount);
            }
        }
        JSONArray amountDetail = JSONArray.parseArray(JSONArray.toJSONString(purchaseInvoiceAmountDetailVO.getAmountDetail()));
        JSONArray paySheetArray = data.getJSONArray(PurchaseInvoiceEnum.PAY_SHEET_ID.getAttr());
        List<Long> paySheetiList = new ArrayList<>();
        if(CollectionsUtil.isNotEmpty(paySheetArray)){
            for(int i=0;i<paySheetArray.size();i++){
                JSONObject paySheetObject = paySheetArray.getJSONObject(i);
                paySheetiList.add(paySheetObject.getLong(BasicConstant.ID));
            }
            Map<Long,String> paySheetTypeMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put("corpid",corpid);
            map.put("idIn",paySheetiList);
            map.put("del", BasicConstant.ZERO);
            List<PaasFormDataEntityExt> paySheetEntityList = payPlanSheetModel.findEntitys(map);
            paySheetEntityList.forEach(item -> {
                JSONObject jsonObject = item.getData();
                String paySheetType = jsonObject.getString(PaySheetEnum.PAY_SHEET_TYPE.getAttr());
                paySheetTypeMap.put(item.getId(),paySheetType);
            });
            for(int i=0;i<paySheetArray.size();i++){
                JSONObject paySheetObject = paySheetArray.getJSONObject(i);
                String paySheetType = paySheetTypeMap.getOrDefault(paySheetObject.getLong(BasicConstant.ID),"");
                paySheetObject.put(InvoiceConstant.PAY_SHEET_TYPE,paySheetType);
            }
        }
        result.put(PaasConstant.AMOUNTDETAIL, amountDetail);
        /*if(Objects.equals(purchaseInvoiceAmountDetailGetDTO.getIsRed(),BasicConstant.ONE) || Objects.equals(purchaseInvoiceAmountDetailGetDTO.getFormRed(),BasicConstant.ONE)){
            explains.forEach(fieldAttrEntity -> {
                if(Objects.equals(PurchaseInvoiceEnum.PAY_RELATIONSHIP.getAttr(),fieldAttrEntity.getAttr())
                        || Objects.equals(PurchaseInvoiceEnum.PURCHASE_ID.getAttr(),fieldAttrEntity.getAttr())
                        || Objects.equals(PurchaseInvoiceEnum.PAY_PLAN_ID.getAttr(),fieldAttrEntity.getAttr())
                        || Objects.equals(PurchaseInvoiceEnum.PAY_SHEET_ID.getAttr(),fieldAttrEntity.getAttr())){
                    fieldAttrEntity.setEditable(0);
                }
            });
        }*/
        fundHelp.setInvoiceNotEditToExplain(explains,purchaseInvoiceAmountDetailGetDTO.getFormRed(),purchaseInvoiceAmountDetailGetDTO.getIsRed(),XbbRefTypeEnum.PURCHASE_INVOICE.getCode());
    }

    public Boolean checkInvoiceHighLevelEdit(List<FieldAttrEntity> originFieldList, HandlerExplainDTO handlerExplainDTO, InvoiceEnum invoiceEnum) throws XbbException{
        boolean flag = false;
        for (FieldAttrEntity fieldAttrEntity : originFieldList){
            if(Objects.equals(fieldAttrEntity.getAttr(),invoiceEnum.getAttr())){
                flag =  ExplainUtil.isEditableOfScope(fieldAttrEntity, handlerExplainDTO);
            }
        }
        return flag;
    }
}
